package com.zyz.system.service.sysuser.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zyz.common.core.active.Time;
import com.zyz.common.core.constants.HttpConstants;
import com.zyz.common.core.enums.ResultCodeEnum;
import com.zyz.common.core.enums.UserIdentity;
import com.zyz.common.core.model.LoginUser;
import com.zyz.common.core.model.LoginUserVO;
import com.zyz.common.core.model.Result;
import com.zyz.common.security.exception.ServiceException;
import com.zyz.common.security.service.TokenService;
import com.zyz.system.mapper.sysuser.SysUserMapper;
import com.zyz.system.model.sysuser.SysUser;
import com.zyz.system.service.sysuser.ISysUserService;
import com.zyz.system.utils.BCryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Slf4j
@RefreshScope
@Service
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Value("${jwt.secret}")
    private String secret;

    @Autowired
    private TokenService tokenService;


    @Override
    public Result<String> login(String userAccount, String password) {
        // 通过账号查询用户密码
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(SysUser::getUserId,SysUser::getPassword,SysUser::getNickName)
                    .eq(SysUser::getUserAccount, userAccount);
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper);

        if (sysUser == null) {
            return Result.fail(ResultCodeEnum.FAILED_USER_NOT_EXISTS);
        }
        if (BCryptUtil.matches(password, sysUser.getPassword())) {
            // 调用tokenService生成token将结果返回给前端
            String token = tokenService.createToken(sysUser.getUserId(),secret,
                    UserIdentity.ADMIN.getValue(),sysUser.getNickName(),null);
            return Result.ok(token);
        }
        return Result.fail(ResultCodeEnum.FAILED_LOGIN);
    }

    @Override
    public boolean logout(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        token = tokenStartCut(token);
        // 通过token获取key并删除redis中的用户信息
        return tokenService.deleteUserInfo(token,secret);
    }

    @Override
    public Result<Void> add(String userAccount, String password, String nickName) {
        // 查询用户账号是否已经存在
        if (checkExists(userAccount)) {
            // 用户账号已经存在
            // 抛异常
            log.error("用户账号已经存在 userAccount: {}",userAccount);
            throw new ServiceException(ResultCodeEnum.FAILED_USER_EXISTS);
        }
        // 新增操作
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(userAccount);
        sysUser.setPassword(BCryptUtil.encrypt(password));
        sysUser.setNickName(nickName);
        int row = sysUserMapper.insert(sysUser);
        if (row != 1) {
            // 抛异常
            log.error("新增system用户错误！userAccount: {}",userAccount);
            throw new ServiceException(ResultCodeEnum.ERROR);
        }
        return Result.ok();
    }
//    @Time
    @Override
    public Result<LoginUserVO> info(String token) {
//        log.info("token: {}", token);
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        token = tokenStartCut(token);
        // 根据token并调用redis拿到redis中的user信息
        LoginUser loginUser = tokenService.getLoginUser(token, secret);
        if (loginUser == null) {
            return Result.fail();
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());
        return Result.ok(loginUserVO);
    }

    private String tokenStartCut(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StringUtils.hasLength(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, "");
        }
        return token;
    }


    private boolean checkExists(String userAccount) {
        // 查询用户账号是否已经存在
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserAccount, userAccount);
        Long count = sysUserMapper.selectCount(queryWrapper);
        return count == 1;
    }
}
